package com.example.mall.service.impl;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mall.client.AuthFeignClient;
import com.example.mall.constants.BaseConstants;
import com.example.mall.domain.Login;
import com.example.mall.domain.User;
import com.example.mall.domain.UserMemberships;
import com.example.mall.domain.UserPoints;
import com.example.mall.dto.RegisterDto;
import com.example.mall.dto.UserDto;
import com.example.mall.mapper.LoginMapper;
import com.example.mall.mapper.UserMapper;
import com.example.mall.mapper.UserMembershipsMapper;
import com.example.mall.mapper.UserPointsMapper;
import com.example.mall.query.PageDTO;
import com.example.mall.query.UserQuery;
import com.example.mall.result.JSONResult;
import com.example.mall.service.IUserService;
import com.example.mall.util.AssertUtil;
import com.example.mall.util.CodeGenerateUtils;
import com.example.mall.util.CopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author whale
 * @since 2025-05-14
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuthFeignClient authFeignClient;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
//    @Autowired
//    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserMembershipsMapper userMembershipsMapper;
    @Autowired
    private UserPointsMapper userPointsMapper;
    @Autowired
    private LoginMapper loginMapper;
    /**
     * 注册
     * @param registerDto
     * @return
     */
    @Override
//    @GlobalTransactional(rollbackFor = Exception.class)//分布式事务，可以回退多模块数据
    public void register(RegisterDto registerDto) {
        //1.基本参数校验
        String mobile = registerDto.getMobile();
        String password = registerDto.getPassword();
        Integer regChannel = registerDto.getRegChannel();
        String smsCode = registerDto.getSmsCode();
        AssertUtil.isPhone(mobile,"无效的手机号");
        AssertUtil.isNotEmpty(password,"密码不能为空");
        AssertUtil.isNotNull(regChannel,"无效的参数regChannel");
        AssertUtil.isNotEmpty(smsCode,"手机验证码不能为空");
        //2.校验验证码
        User userPhone = baseMapper.selectByPhone(mobile);
        AssertUtil.isNull(userPhone,"该手机号已注册");
        //3.获取短信验证码
        String smsCode2Cache = (String) redisTemplate.opsForValue().get(mobile+":"+smsCode);
        // 3.1 验证码是否为空
        AssertUtil.isNotNull(smsCode2Cache,"验证码不存在");
        // 3.2 redis中的验证码和传入的参数的验证码比较
        AssertUtil.isEqualsIgnoreCase(smsCode2Cache,smsCode,"验证码不正确");

        //4.注册登录信息
        Login login = new Login();

        login.setPassword(password);
        //头像
        login.setAvatar("https://img2.baidu.com/it/u=1535346744,3172439964&fm=26&fmt=auto");
        //前台用户分配的客户端ID
        login.setClientId("website");
        login.setClientSecret("123");
        login.setType(BaseConstants.Login.TYPE_USER);
        login.setUsername(mobile);
        login.setEnabled(BaseConstants.EFFECTIVE_STATUS);
        login.setAccountNonExpired(BaseConstants.EFFECTIVE_STATUS);
        login.setAccountNonLocked(BaseConstants.EFFECTIVE_STATUS);
        JSONResult jsonResult = authFeignClient.insert(login);
        AssertUtil.isTrue(jsonResult.isSuccess(),"登录信息保存失败");

        //5.注册用户信息
        User user = new User();
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setPhone(mobile);
        //密码加密
        user.setSalt(login.getPassword());
        user.setNickName(mobile);
        //增加手机的位状态
        user.setBitState(BaseConstants.User.STATE_PHONE);
        user.setLoginId(login.getId());
        userMapper.insert(user);

        //6.新增用户会员信息
        UserMemberships userMemberships = new UserMemberships();
        userMemberships.setUserId(user.getId());
        userMemberships.setLevelId(0L);
        userMemberships.setStartTime(new Date());
        userMemberships.setEndTime(new Date());
        userMemberships.setCreateTime(new Date());
        userMemberships.setUpdateTime(new Date());
        userMembershipsMapper.insert(userMemberships);

        //7.新增用户积分信息
        UserPoints userPoints = new UserPoints();
        userPoints.setUserId(user.getId());
        userPoints.setPoints(0);
        userPoints.setDescription("初始化账号积分");
        userPoints.setCreateDate(new Date());
        userPoints.setUpdateDate(new Date());
        userPointsMapper.insert(userPoints);

        //8.删除redis中的验证码
        redisTemplate.delete(BaseConstants.SMS_PHONE_KEY + mobile);

    }

    @Override
    public PageDTO<UserDto> queryPage(UserQuery userQuery) {
        if (userQuery == null) {
            userQuery = new UserQuery();
        }
        Page<User> page = userQuery.toMpPageByDefaultCreateTimeAsc();
        Page<User> cartPage = lambdaQuery()
                .like(userQuery.getId()!= null, User::getId, userQuery.getId())
                .like(userQuery.getThirdUid()!= null, User::getThirdUid, userQuery.getThirdUid())
                .eq(userQuery.getPhone()!= null, User::getPhone, userQuery.getPhone())
                .like(userQuery.getEmail()!= null, User::getEmail, userQuery.getEmail())
                .like(userQuery.getAvatar()!= null, User::getAvatar, userQuery.getAvatar())
                .like(userQuery.getSalt()!= null, User::getSalt, userQuery.getSalt())
                .like(userQuery.getNickName()!= null, User::getNickName, userQuery.getNickName())
                .eq(userQuery.getBitState()!= null, User::getBitState, userQuery.getBitState())
                .eq(userQuery.getSecLevel()!= null, User::getSecLevel, userQuery.getSecLevel())
                .orderByDesc(User::getUpdateTime)
                .page(page);
        return PageDTO.of(cartPage, UserDto.class);
    }

    @Override
    public User queryUserById(Long id) {
        AssertUtil.isNotNull(id,"无效的参数id");
        return userMapper.selectById(id);
    }

    @Override
    public List<User> queryUserList() {
        return this.list();
    }

    @Override
    public void insert(UserDto userDto) {
        User user = new User();
        CopyUtils.copyProperties(userDto,user);
        user.setId(CodeGenerateUtils.generateUniqueId());
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setBitState(Long.valueOf(BaseConstants.EFFECTIVE_STATUS));
        userMapper.insert(user);
    }

    @Override
    public void update(UserDto userDto) {
        AssertUtil.isNotNull(userDto.getId(),"无效的参数id");
        User user = userMapper.selectById(userDto.getId());
        AssertUtil.isNotNull(user,"无效的参数id");
        CopyUtils.copyProperties(userDto,user);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
    }

    @Override
    public void delete(Long id) {
        AssertUtil.isNotNull(id,"无效的参数id");
        User user = userMapper.selectById(id);
        AssertUtil.isNotNull(user,"无效的参数id");
        user.setBitState(Long.valueOf(BaseConstants.LOSE_STATUS));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
    }

    @Override
    public void deleteBatch(List<Long> ids) {
        AssertUtil.isNotNull(ids,"无效的参数ids");
        List<User> users = userMapper.selectBatchIds(ids);
        AssertUtil.isNotNull(users,"无效的参数ids");
        for (User user : users) {
            user.setBitState(Long.valueOf(BaseConstants.LOSE_STATUS));
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
    }
}
